#include <iostream>
using namespace std;

class Father{
    private:
        string name;
        int *age;
    public:
        Father():name("admin"), age(new int(0)){
            cout << "Father 无参构造" << endl;
        }
        Father(string n, int a):name(n), age(new int (a)){
            cout << "Father 有参构造" << endl;
        }
        Father(const Father &other):name(other.name), age(new int (*other.age)){
            cout << "Father 拷贝构造" << endl;
        }
        Father &operator=(const Father &other){
            if(this != &other){
                delete age;
                name = other.name;
                age = new int(*other.age);
            }
            return *this;
        }
        ~Father(void){
            delete age;
            age = nullptr;
            cout << "Father 析构函数" << endl;
        }
        void show(){
            cout << name << " " << *age << endl;
        }
};

class Son:public Father{
    private:
        int tel;
    public:
        // 这种写法也不可以 因为 name 和 age 不是 Son 类的成员
        //Son(string n, int a, int t):name(n), age(new int(a)), tel(t){

        // 需要在子类构造函数的初始化表中调用父类的构造函数
        Son(string n, int a, int t):Father(n, a), tel(t){
            // Father(n, a); // 构造函数不能手动调用
            // 这种写法不是调用父类构造函数 而是在此处实例化了一个Father类的匿名对象
            cout << "Son 有参构造" << endl;
        }
        Son(const Son &other):Father(other), tel(other.tel){// 这里传参用到了:父类的引用可以引用子类对象
            cout << "Son 拷贝构造" << endl;
        }
        Son &operator=(const Son &other){
            if(this != &other){
                Father::operator=(other); // 调用父类的拷贝赋值函数 // 这里传参用到了:父类的引用可以引用子类对象
                this->tel = other.tel;
            }
            return *this;
        }
        ~Son(void){
            cout << "Son 析构函数" << endl;
        }
        void show(){
            Father::show();
            cout << tel << endl;
        }
};

int main(int argc, const char *argv[]){
    Son s1("小明", 18, 123456);
    s1.show();

    cout << "--------------" << endl;

    Son s2(s1); // 调用拷贝构造
    s2.show();

    cout << "--------------" << endl;
    
    Son s3("小红", 20, 111222);
    s3 = s1; // 调用拷贝赋值
    s3.show();

    return 0;
}